package com.ship.contract.controller;

import bsh.EvalError;
import bsh.Interpreter;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ship.common.business.mapping.BooleanContentProvider;
import com.ship.common.business.mapping.EnumContentProvider;
import com.ship.common.business.service.BaseService;
import com.ship.common.core.domain.R;
import com.ship.common.core.exception.ServiceException;
import com.ship.common.redis.service.RedisService;
import com.ship.contract.service.ExportService;
import com.ship.common.business.service.impl.BaseServiceImpl;
import com.ship.common.core.base.*;
import com.ship.common.core.exception.BusException;
import com.ship.common.core.exception.SystemException;
import com.ship.common.core.mapping.*;
import com.ship.common.core.utils.*;
import com.ship.common.core.web.domain.BaseResultCode;
import com.ship.common.core.web.domain.JsonResult;
import com.ship.common.log.annotation.Log;
import com.ship.common.log.enums.BusinessType;
import com.ship.common.security.utils.SecurityUtils;
import com.ship.contract.bean.ConAllLabel;
import com.ship.contract.bean.ConFiles;
import com.ship.contract.bean.ConLabel;
import com.ship.contract.bean.PayFundManagement;
import com.ship.contract.bean.dto.PayFundManagementDto;
import com.ship.contract.service.*;
import com.ship.contract.task.ExportContractFileTask;
import com.ship.contract.utils.ModuleConst;
import com.ship.contract.service.SearchConfigService;
import com.ship.contract.service.TableConfigService;
import com.ship.system.api.RemoteFileService;
import com.ship.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.util.StringUtil;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author tangshixuan
 * @date 2023-8-30
 */
@RestController
@RequestMapping("/common")
@Api(value = "common", tags = "合同公共common")
public class CommonController extends BaseController implements InitializingBean {
    private static final Logger logger = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private SpringUtil springUtil;

    @Autowired
    private EnumContentProvider enumContentProvider;

    @Autowired
    private BooleanContentProvider booleanContentProvider;

    @Autowired
    private TableConfigService tableConfigService;

    @Autowired
    private SearchConfigService searchConfigService;

    @Autowired
    private ConLabelService conLabelService;

    @Autowired
    private ConAllLabelService conAllLabelService;

    @Autowired
    private ConFilesService conFilesService;

    @Autowired
    private ConOperateService conOperateService;

    @Autowired
    private HttpRequestUtil httpRequestUtil;

    @Autowired
    private ExportService exportService;

    @Autowired
    private RemoteFileService remoteFileService;

    @Autowired
    private ConResourceMemorandumPositionService conResourceMemorandumPositionService;

    @Autowired
    private SpInformationService spInformationService;

    @Autowired
    private PayFundManagementService payFundManagementService;

    @Value("${file_server.host}")
    private String fileServerHost;

    @Autowired
    private RedisService redisService;

    private static final String FILE_UPLOAD_PATH = "/group1/upload";

    private Map<String, List<Field>> searchItems = new HashMap<>();

    private Map<String, List<Field>> tableColumns = new HashMap<>();

    /**
     * 获取用户配置的列表展示列
     * @param module
     * @return
     */
    @RequestMapping("/getCurrentUserTableColumn")
    public JsonResult getCurrentUserTableColumn(String module){
        String id = SecurityUtils.getStringUserId();
        List<TableConfig> tableConfigList = tableConfigService.listByModuleAndUser(module, SecurityUtils.getUserId());
        if (CollectionUtil.isEmpty(tableConfigList)){
            Integer orderNum = 0 ;
            for (Field field : tableColumns.get(module)) {
                Label label = field.getAnnotation(Label.class);
                TableColumn tableColumn = field.getAnnotation(TableColumn.class);
                orderNum = orderNum + 1;
                TableConfig tableConfig = new TableConfig();
                tableConfig.setColumnKey(field.getName());
                tableConfig.setFixed(0);
                tableConfig.setOrderNum(orderNum);
                tableConfigList.add(tableConfig);
            }
        }
        return JsonResult.success(tableConfigList);
    }

    @GetMapping("")
    public String test(){
        return "succeed";
    }

    /**
     * 保存用户列表展示列配置
     * @param jsonObject
     * @return
     */
    @PostMapping("/saveTableColumn")
    public JsonResult saveTableColumn(@RequestBody JSONObject jsonObject){
        tableConfigService.saveConfig(jsonObject,SecurityUtils.getStringUserId());
        return JsonResult.success();
    }

    /**
     * 获取模块所有列
     * @param module
     * @return
     */
    @RequestMapping("/getTableColumn")
    public JsonResult getTableColumn(String module) {
        JSONArray items = new JSONArray();
        if (!tableColumns.containsKey(module)) {
            return JsonResult.success(items);
        }
        for (Field field : tableColumns.get(module)) {
            Label label = field.getAnnotation(Label.class);
            TableColumn tableColumn = field.getAnnotation(TableColumn.class);
            JSONObject item = new JSONObject();
            item.put("key", field.getName());
            item.put("name", label.value()[0]);
            item.put("priority", label.priority());
            if (tableColumn.abbr() != 0) {
                item.put("abbr", tableColumn.abbr());
            }
            if (tableColumn.width() != 0) {
                item.put("width", tableColumn.width() + "px");
            }
            if (tableColumn.sortable() && field.getAnnotation(Transient.class) == null) {
                item.put("sortable", "custom");
            }
            if (!tableColumn.tagType().equals("")) {
                item.put("tagType", tableColumn.tagType());
            }
            if(!tableColumn.children().equals("")){
                item.put("name", "");
                item.put("align","center");
                String childrens = tableColumn.children();
                String[] childrensColumn = childrens.split(",");
                JSONArray ja = new JSONArray();
                for (String column: childrensColumn){
                    JSONObject i = new JSONObject();
                    i.put("key",column.split(":")[0]);
                    i.put("name",column.split(":")[1]);
                    ja.add(i);
                }
                item.put("children",ja);
            }
            items.add(item);
        }
        return JsonResult.success(items);
    }

    /**
     * 获取用户配置的筛选条件列
     * @param module
     * @return
     */
    @RequestMapping("/getCurrentUserQueryItem")
    public JsonResult getCurrentUserQueryItem(String module){
        return JsonResult.success(searchConfigService.listByModuleAndUser(module,SecurityUtils.getStringUserId()));
    }

    /**
     * 保存用户筛选条件配置
     * @param searchConfig
     * @return
     */
    @PostMapping("/saveQueryItem")
    public JsonResult saveQueryItem(@RequestBody SearchConfig searchConfig){
        searchConfig.setUserId(SecurityUtils.getUserId());
        searchConfigService.saveConfig(searchConfig);
        return JsonResult.success();
    }

    /**
     * 删除条件筛选配置
     * @param id
     * @return
     */
    @DeleteMapping("/delQueryItem")
    public JsonResult delQueryItem(Long id){
        searchConfigService.removeById(id);
        return JsonResult.success();
    }

    /**
     * 查询所有筛选条件
     * @param module
     * @return
     */
    @RequestMapping("/getQueryItem")
    public JsonResult<Object> getQueryItem(String module){
        JSONArray items = new JSONArray();
        if (!searchItems.containsKey(module)) {
            return JsonResult.success(items);
        }
        for (Field field : searchItems.get(module)) {
            JSONObject item = createSearchItem(field);
            if (item != null) {
                String dataType = item.getString("type");
                String format = getFieldDateFormat(field);
                if ("date".equals(dataType)) {
                    item.put("type", "daterange");
                    item.put("importminwidth", "120");
                    if (StringUtils.isNotBlank(format)) {
                        item.put("valueFormat", format);
                    } else {
                        item.put("valueFormat", "YYYY-MM-DD");
                    }
                }
                if ("month".equals(dataType)) {
                    item.put("valueFormat", "yyyy-MM");
                }
                if ("datetimerange".equals(dataType)) {
                    if (format != null) {
                        item.put("valueFormat", format);
                    } else {
                        item.put("valueFormat", "YYYY-MM-DD");
                    }
                }
                items.add(item);
            }
        }
        return JsonResult.success(items);
    }

    /**
     * 获取系统标签
     * @return
     */
    @RequestMapping("/getSystemLabel")
    public JsonResult<List<ConLabel>> getSystemLabel(){
        return JsonResult.success(conLabelService.list());
    }

    /**
     * 保存合同标签
     * @return
     */
    @PostMapping("/saveContractLabel")
    public JsonResult saveContractLabel(@RequestBody ConAllLabel conAllLabel){
        conAllLabel.setUserId(SecurityUtils.getUserId());
        conAllLabelService.saveContractLabel(conAllLabel);
        conOperateService.saveByCon("新增标签",conAllLabel.getConId());
        return JsonResult.success(conAllLabel.getId());
    }

    /**
     * 上传合同附件
     * @return
     */
    @PostMapping("/uploadContractFiles")
    @Log(title = "上传合同附件",businessType = BusinessType.IMPORT)
    public JsonResult uploadContractFiles(@RequestBody ConFiles conFiles){
        conFiles.setFileType(2);
        conFilesService.save(conFiles);
        conOperateService.saveByCon("上传附件",conFiles.getConId());
        return JsonResult.success(conFiles.getId());
    }



    /**
     * 上传附件
     *
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ResponseBody
    public JsonResult<Object> upload(@RequestParam("file") MultipartFile file) {
        FileUtils.checkFileName(file);
        String httpUrl = "";
        try {
            R<SysFile> result = remoteFileService.upload(file);
            if (result.getCode() != R.SUCCESS) {
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }
            httpUrl = result.getData().getHttpUrl();
        } catch (Exception e) {
            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
        }
        return JsonResult.success(httpUrl);
    }

    @PostMapping("/uploadHttps")
    @ResponseBody
    public JsonResult<Object> uploadHttps(@RequestParam("file") MultipartFile file) {
        FileUtils.checkFileName(file);
        String httpUrl = "";
        try {
            R<SysFile> result = remoteFileService.upload(file);
            if (result.getCode() != R.SUCCESS) {
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }
            httpUrl = result.getData().getHttpsUrl();
        } catch (Exception e) {
            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
        }
        return JsonResult.success(httpUrl);
    }


    @PostMapping("/testocr")
    @ResponseBody
    public JsonResult<Object> testocr(@RequestParam("file") MultipartFile file) {
        JSONObject ocrData = httpRequestUtil.testocr(file);
        return JsonResult.success(ocrData);
    }

    /**
     * 上传资源合同附件、船运合同附件
     *
     * @param file
     * @return
     */
    @ApiOperation(value = "上传资源合同附件、船运合同附件")
    @PostMapping("/uploadContract")
    public JsonResult uploadShipReport(@RequestParam("file") MultipartFile file) {
        FileUtils.checkFileName(file);
        String httpUrl = "";
        try {

            R<SysFile> result = remoteFileService.upload(file);
            if (result.getCode() != R.SUCCESS) {
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }

            httpUrl = result.getData().getHttpUrl();
            return JsonResult.success(httpUrl);
        } catch (Exception e) {
            return JsonResult.failed("上传失败，原因：" + e.getMessage());
        }
    }

    @PostMapping("/uploadContractWithtest")
    @ResponseBody
    public JsonResult<Object> uploadContractWithtest(String filePath)  {
        String shapeName = filePath;
        String modifiedShapeName = shapeName.replaceAll("(?<!^)(?=[A-Z])", " ").toUpperCase();
        modifiedShapeName = modifiedShapeName.replaceAll("\\s{2,}", " ");
        return JsonResult.success(modifiedShapeName);
    }

    /**
     * 通过附件路径，解析数据(资源合同、船运合同)
     *
     * @param filePath
     * @return
     */
    @PostMapping("/uploadContractWithAnalysisNew")
    @ResponseBody
    public JsonResult<Object> uploadContractWithAnalysisNew(String filePath,String contractType)  {
        if(StringUtils.isEmpty(filePath)){
            return JsonResult.failed("filePath为空");
        }
        String fileOriginalName = filePath.substring(filePath.lastIndexOf("/") + 1);
        Map map = new HashMap(4);
        //调用OCR接口获取数据并返回
        JSONObject jo = new JSONObject();
        if(StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.CON_RESOURCE_MEMORANDUM)){
            JSONObject ocrData = httpRequestUtil.ocrNew1(filePath);
            if(ocrData != null){
                //处理备忘录数据
                jo.put("signingDateStrName","date");
                jo.put("signingDateStrVal",ocrData.getString("date").trim());
                jo.put("signingDateName","date");
                jo.put("signingDateVal","");
                jo.put("signingDateLocName","date_loc");
                jo.put("signingDateLocVal",ocrData.getJSONObject("date_loc"));
                jo.put("buyerName","buyer");
                jo.put("buyerVal",ocrData.getString("buyer").trim());
                jo.put("buyerLocName","buyer_loc");
                jo.put("buyerLocVal",ocrData.getJSONObject("buyer_loc"));
                jo.put("sellerName","seller");
                jo.put("sellerVal",ocrData.getString("seller").trim());
                jo.put("sellerLocName","seller_loc");
                jo.put("sellerLocVal",ocrData.getJSONObject("seller_loc"));
                jo.put("deliveryTypeLocName","incoterms_loc");
                jo.put("deliveryTypeLocVal",ocrData.getJSONObject("incoterms_loc"));
                jo.put("loadingPortName","loading port");
                jo.put("loadingPortVal",ocrData.getString("loading port").trim());
                jo.put("loadingPortLocName","loading_port_loc");
                jo.put("loadingPortLocVal",ocrData.getJSONObject("loading_port_loc"));
                jo.put("unloadingPortName","discharge port");
//                jo.put("unloadingPortVal",ocrData.getString("discharge port").trim());

                if ((ocrData.getString("discharge port").trim().isEmpty())) {
                    jo.put("unloadingPortVal","No restriction");
                }else {
                    jo.put("unloadingPortVal",ocrData.getString("discharge port").trim());
                }

                jo.put("unloadingPortLocName","discharge_port_loc");
                jo.put("unloadingPortLocVal",ocrData.getJSONObject("discharge_port_loc"));
                jo.put("deliveryWindowName","delivery window");
                jo.put("deliveryWindowVal",ocrData.getString("delivery window").trim());
                jo.put("deliveryWindowLocName","delivery_window_loc");
                jo.put("deliveryWindowLocVal",ocrData.getJSONObject("delivery_window_loc"));
                jo.put("loadingOrUnloadingCapacityLocName","quantities_loc");
                jo.put("loadingOrUnloadingCapacityLocVal",ocrData.getJSONObject("quantities_loc"));
                jo.put("shipNameName","shape name");
                jo.put("shipNameVal",ocrData.getString("shape name").trim());
                jo.put("shipNameLocName","shape_name_loc");
                jo.put("shipNameLocVal",ocrData.getJSONObject("shape_name_loc"));
                jo.put("imoName","IMO");
                jo.put("imoVal",ocrData.getString("IMO").trim());
                jo.put("imoLocName","IMO_loc");
                jo.put("imoLocVal",ocrData.getJSONObject("IMO_loc"));
                jo.put("demurrageRateLocName","demurrage_rate_loc");
                jo.put("demurrageRateLocVal",ocrData.getJSONObject("demurrage_rate_loc"));
                jo.put("allowLoadingTimeLocName","laytime_loc");
                jo.put("allowLoadingTimeLocVal",ocrData.getJSONObject("laytime_loc"));
                jo.put("evaporationRateLocName","boil_off_rate_loc");
                jo.put("evaporationRateLocVal",ocrData.getJSONObject("boil_off_rate_loc"));
                jo.put("measurementClauseLocName","measurement_loc");
                jo.put("measurementClauseLocVal",ocrData.getJSONObject("measurement_loc"));
                jo.put("downFloatValueLocName","min_operational_tolerance_loc");
                jo.put("downFloatValueLocVal",ocrData.getJSONObject("min_operational_tolerance_loc"));
                jo.put("downFloatValueLoc",ocrData.getJSONObject("min_operational_tolerance_loc"));
                jo.put("upFloatValueLocName","max_operational_tolerance_loc");
                jo.put("upFloatValueLocVal",ocrData.getJSONObject("max_operational_tolerance_loc"));
                jo.put("upFloatValueLoc",ocrData.getJSONObject("max_operational_tolerance_loc"));
                jo.put("fileId",fileOriginalName);
                jo.put("msg","SUCCESS");
                jo.put("detectStatus","1");
                jo.put("signingDate","");
                jo.put("buyer",ocrData.getString("full_buyer").trim());
//                jo.put("buyer",ocrData.getString("buyer").trim());
                jo.put("seller",ocrData.getString("full_seller").trim());
//                jo.put("seller",ocrData.getString("seller").trim());
                jo.put("fullBuyer",ocrData.getString("full_buyer").trim());
                jo.put("fullSeller",ocrData.getString("full_seller").trim());
                jo.put("loadingPort",ocrData.getString("loading port").trim());

                String buyerTradeBody = ocrData.getString("full_buyer").replaceAll("\\s", "");
                if (buyerTradeBody.endsWith("Ltd")) {
                    jo.put("buyerTradeBody", 2);
                } else if (buyerTradeBody.endsWith("ted")) {
                    jo.put("buyerTradeBody", 1);
                } else {
                    jo.put("buyerTradeBody", "");
                }

                String sellerTradeBody = ocrData.getString("full_seller").replaceAll("\\s", "");
                if (sellerTradeBody.endsWith("Ltd")) {
                    jo.put("sellerTradeBody", 2);
                } else if (sellerTradeBody.endsWith("ted")) {
                    jo.put("sellerTradeBody", 1);
                } else {
                    jo.put("sellerTradeBody", "");
                }

                if ((ocrData.getString("discharge port").trim().isEmpty())) {
                    jo.put("unloadingPort","No restriction");
                }else {
                    jo.put("unloadingPort",ocrData.getString("discharge port").trim());
                }
                jo.put("deliveryWindow",ocrData.getString("delivery window").trim());
                jo.put("shipName",ocrData.getString("shape name").trim());
                jo.put("imo",ocrData.getString("IMO").trim());
                try {
                    jo.put("downFloatValueName","min_operational_tolerance");
                    jo.put("downFloatValueVal",new BigDecimal(ocrData.getString("min_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("downFloatValue",new BigDecimal(ocrData.getString("min_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("downFloatValueName","");
                    jo.put("downFloatValueVal","");
                    jo.put("downFloatValue",0);
                }
                try {
                    jo.put("upFloatValueName","max_operational_tolerance");
                    jo.put("upFloatValueVal",new BigDecimal(ocrData.getString("max_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("upFloatValue",new BigDecimal(ocrData.getString("max_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("upFloatValueName","");
                    jo.put("upFloatValueVal","");
                    jo.put("upFloatValue",0);
                }
                try {
                    jo.put("measurementClauseName","measurement");
                    jo.put("measurementClauseVal",ocrData.getString("measurement").replaceAll(",","").replaceAll("，","").trim());
                    jo.put("measurementClause",ocrData.getString("measurement").replaceAll(",","").replaceAll("，","").trim());
                }catch (Exception e){
                    jo.put("measurementClauseName","");
                    jo.put("measurementClauseVal","");
                    jo.put("measurementClause","");
                }
                try {
                    String quantitiesString = ocrData.getString("quantities").replaceAll("[Oo]", "0").replaceAll("[^0-9]", "");
                    BigDecimal quantities = new BigDecimal(quantitiesString);
                    jo.put("loadingOrUnloadingCapacityName", "quantities");
                    jo.put("loadingOrUnloadingCapacityVal", quantities);
                    jo.put("loadingOrUnloadingCapacity", quantities);
                }catch (Exception e){
                    jo.put("loadingOrUnloadingCapacityName","");
                    jo.put("loadingOrUnloadingCapacityVal","");
                    jo.put("loadingOrUnloadingCapacity","");
                }
                try {
                    jo.put("demurrageRateName","demurrage rate");
                    jo.put("demurrageRateVal",new BigDecimal(ocrData.getString("demurrage rate").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("demurrageRate",new BigDecimal(ocrData.getString("demurrage rate").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("demurrageRateName","");
                    jo.put("demurrageRateVal","");
                    jo.put("demurrageRate","");
                }
                try {
                    jo.put("evaporationRateName","boil off rate");
                    jo.put("evaporationRateVal",new BigDecimal(ocrData.getString("boil off rate").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("evaporationRate",new BigDecimal(ocrData.getString("boil off rate").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("evaporationRateName","");
                    jo.put("evaporationRateVal","");
                    jo.put("evaporationRate","");
                }
                try {
                    jo.put("allowLoadingTimeName","laytime");
                    jo.put("allowLoadingTimeVal",ocrData.getInteger("laytime"));
                    jo.put("allowLoadingTime",ocrData.getInteger("laytime"));
                }catch (Exception e){
                    jo.put("allowLoadingTimeName","");
                    jo.put("allowLoadingTimeVal","");
                }
                String deliveryType = ocrData.getString("incoterms_info").trim();
                jo.put("deliveryTypeName","incoterms_info");
                if(deliveryType.equals("FOB")){
                    jo.put("deliveryType",1);
                    jo.put("deliveryTypeVal","FOB");

                }else if(deliveryType.equals("DES")){
                    jo.put("deliveryTypeVal","DES");
                    jo.put("deliveryType",2);
                }
                String demurrageType = ocrData.getString("demurrage_type").trim();
                jo.put("currencyName","demurrage_type");
                if(demurrageType.equals("USD")){
                    jo.put("currency",1);
                    jo.put("currencyVal","USD");
                } else if(demurrageType.equals("CNY")){
                    jo.put("currency",2);
                    jo.put("currencyVal","CNY");
                } else if(demurrageType.equals("EUR")) {
                    jo.put("currency", 3);
                    jo.put("currencyVal","EUR");
                } else if(demurrageType.equals("GBP")) {
                    jo.put("currency", 4);
                    jo.put("currencyVal","GBP");
                } else if(demurrageType.equals("CAD")) {
                    jo.put("currency", 5);
                    jo.put("currencyVal","CAD");
                } else if(demurrageType.equals("JPY")) {
                    jo.put("currency", 6);
                    jo.put("currencyVal","JPY");
                } else if(demurrageType.equals("INR")) {
                    jo.put("currency", 7);
                    jo.put("currencyVal","INR");
                } else if(demurrageType.equals("PENCE")) {
                    jo.put("currency", 8);
                    jo.put("currencyVal","PENCE");
                } else if(demurrageType.equals("RUB")) {
                    jo.put("currency", 9);
                    jo.put("currencyVal","RUB");
                }
                String quantitiesType = ocrData.getString("quantities_type").trim();
                jo.put("unitName","quantities_type");
                if(quantitiesType.equals("MMBTU")){
                    jo.put("unit",1);
                    jo.put("unitVal","MMBTU");
                }else if(quantitiesType.equals("m³")){
                    jo.put("unit",2);
                    jo.put("unitVal","m³");
                }else if(quantitiesType.equals("mt")) {
                    jo.put("unit",3);
                    jo.put("unitVal","mt");
                }
                map.put("contractData",jo);
            }else{
                map.put("contractData",jo);
            }
            map.put("path",filePath);
            conResourceMemorandumPositionService.saveInfo(map,filePath);
        }
        else if (StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.CON_SHIPPING)){
            JSONObject ocrData = httpRequestUtil.ocrNew2(filePath);
            logger.info("返回解析上传文件:"+ JSONUtil.parse(ocrData));
            if(ocrData != null){
                //处理船运数据
                jo.put("tenantName","Charterer");
                jo.put("tenantLocName","Charterer_loc");
                jo.put("shipownerName","Owner");
                jo.put("shipownerLocName","Owner_loc");
                jo.put("shipNameName","Vessel");
                jo.put("shipNameLocName","Vessel_loc");
                jo.put("leaseTermStrName","Period");
                jo.put("leaseTermStrLocName","Period_loc");
                jo.put("deliveryNoticeName","Delivery notices");
                jo.put("deliveryNoticeLocName","Delivery notices_loc");
                jo.put("deliveryDateName","Delivery Laycan");
                jo.put("deliveryDateLocName","Delivery Laycan_loc");
                jo.put("placeOfDeliveryOfShipName","Delivery location");
                jo.put("placeOfDeliveryOfShipLocName","Delivery location_loc");
                jo.put("deliveryStatusName","Delivery condition");
                jo.put("deliveryStatusLocName","Delivery condition_loc");
                jo.put("placeOfRedeliveryOfShipName","Re-delivery");
                jo.put("placeOfRedeliveryOfShipLocName","Re-delivery_loc");
                jo.put("redeliveryStatusName","Re-delivery Condition");
                jo.put("redeliveryStatusLocName","Re-delivery Condition_loc");
                jo.put("redeliveryNoticeName","Re-delivery notices");
                jo.put("redeliveryNoticeLocName","Re-delivery notices_loc");
                jo.put("foeName","FOE");
                jo.put("foeLocName","FOE_loc");
                jo.put("fuelUsagePrinciplesName","Fuel Price");
                jo.put("fuelUsagePrinciplesLocName","Fuel Price_loc");

                jo.put("tenantVal",ocrData.getString("Charterer").trim());
                jo.put("tenant",ocrData.getString("Charterer").trim());
                jo.put("tenantLocVal",ocrData.getJSONObject("Charterer_loc"));
                jo.put("shipownerVal",ocrData.getString("Owner").trim());
                jo.put("shipowner",ocrData.getString("Owner").trim());
                jo.put("shipownerLocVal",ocrData.getJSONObject("Owner_loc"));
                jo.put("shipNameVal",ocrData.getString("Vessel").trim());
//                jo.put("shipName",ocrData.getString("Vessel").trim());
                String shapeName = ocrData.getString("Vessel").trim();
                String modifiedShapeName = shapeName.replaceAll("(?<!^)(?=[A-Z])", " ").toUpperCase();
                modifiedShapeName = modifiedShapeName.replaceAll("\\s{2,}", " ");
                jo.put("shipName",modifiedShapeName);
                jo.put("shipNameLocVal",ocrData.getJSONObject("Vessel_loc"));
                jo.put("leaseTermStrLocVal",ocrData.getJSONObject("Period_loc"));
                jo.put("deliveryNoticeVal",ocrData.getString("Delivery notices").trim());
                jo.put("deliveryNoticeLocVal",ocrData.getJSONObject("Delivery notices_loc"));
                jo.put("deliveryDateVal",ocrData.getString("Delivery Laycan").trim());
                jo.put("deliveryDate","");
                jo.put("deliveryDateLocVal",ocrData.getJSONObject("Delivery Laycan_loc"));
                jo.put("placeOfDeliveryOfShipVal",ocrData.getString("Delivery location").trim());
                jo.put("placeOfDeliveryOfShipLocVal",ocrData.getJSONObject("Delivery location_loc"));
                jo.put("deliveryStatusVal",ocrData.getString("Delivery condition").trim());
                jo.put("deliveryStatusLocVal",ocrData.getJSONObject("Delivery condition_loc"));
                jo.put("placeOfRedeliveryOfShipVal",ocrData.getString("Re-delivery").trim());
                jo.put("placeOfRedeliveryOfShipLocVal",ocrData.getJSONObject("Re-delivery_loc"));

                jo.put("redeliveryStatusLocVal",ocrData.getJSONObject("Re-delivery Condition_loc"));
                jo.put("redeliveryNoticeVal",ocrData.getString("Re-delivery notices").trim());
                jo.put("redeliveryNoticeLocVal",ocrData.getJSONObject("Re-delivery notices_loc"));

                jo.put("foeLocVal",ocrData.getJSONObject("FOE_loc"));

                jo.put("fuelUsagePrinciplesLocVal",ocrData.getJSONObject("Fuel Price_loc"));
                try {
                    jo.put("redeliveryStatusName","Re-delivery Condition");
                    jo.put("redeliveryStatusVal",new BigDecimal(ocrData.getString("Re-delivery Condition").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("redeliveryStatus",new BigDecimal(ocrData.getString("Re-delivery Condition").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("redeliveryStatusName","");
                    jo.put("redeliveryStatusVal","");
                    jo.put("redeliveryStatus","");
                }
                try {
                    jo.put("foeName","FOE");
                    jo.put("foeVal",new BigDecimal(ocrData.getString("FOE").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("foe",new BigDecimal(ocrData.getString("FOE").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("foeName","");
                    jo.put("foeVal","");
                    jo.put("foe","");
                }
                String fuelUsagePrinciples = ocrData.getString("Fuel Price").trim();
                jo.put("fuelUsagePrinciplesName","Fuel Price");
                switch (fuelUsagePrinciples) {
                    case "FIFO":
                        jo.put("fuelUsagePrinciples", 1);
                        jo.put("fuelUsagePrinciplesVal", "FIFO");
                        break;
                    case "LIFO":
                        jo.put("fuelUsagePrinciples", 2);
                        jo.put("fuelUsagePrinciplesVal", "LIFO");
                        break;
                    case "LILO":
                        jo.put("fuelUsagePrinciples", 3);
                        jo.put("fuelUsagePrinciplesVal", "LILO");
                        break;
                }

                String tenant = ocrData.getString("Charterer").replaceAll("\\s", "");
                if (tenant.endsWith("Ltd.")) {
                    jo.put("tradeBody", 2);
                } else if (tenant.endsWith("ted.")) {
                    jo.put("tradeBody", 1);
                } else {
                    jo.put("tradeBody", "");
                }
                String leaseTermStr = ocrData.getString("Period").trim();
                BigDecimal leaseTerm = extractLeaseTerm(leaseTermStr);
                Integer leaseTermValueUp = extractX1(leaseTermStr);
                Integer leaseTermValueUpDown = extractX2(leaseTermStr);
                jo.put("leaseTerm",leaseTerm);
                jo.put("leaseTermValueUp",leaseTermValueUp);
                jo.put("leaseTermValueUpDown",leaseTermValueUpDown);
            }
            map.put("contractData",jo);
            map.put("path",filePath);
            conResourceMemorandumPositionService.saveInfo(map,filePath);
        } else if (StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.TEMPLATE_FILE)){
            int lastIndex = filePath.lastIndexOf("/");
            String fileName = filePath.substring(lastIndex + 1);
            int dotIndex = fileName.lastIndexOf(".");
            String fileNameWithout = fileName.substring(0, dotIndex);
            map.put("contractData",jo);
            map.put("fileName",fileNameWithout);
            map.put("path",filePath);
        }
        else{
            map.put("contractData",jo);
            map.put("path",filePath);
        }
        return JsonResult.success(map);
    }

    /**
     * 上传附件并解析数据(优化以后暂时不使用，使用uploadContractWithAnalysisNew方法)
     *
     * @param file
     * @return
     */
    @PostMapping("/uploadContractWithAnalysis")
    @ResponseBody
    public JsonResult<Object> uploadContractWithAnalysis(@RequestParam("file") MultipartFile file,String contractType)  {
        FileUtils.checkFileName(file);
//        String filePath = httpRequestUtil.upload(file);
        R<SysFile> result = remoteFileService.upload(file);
        if(result.getCode() != R.SUCCESS){
            throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
        }
        String filePath = result.getData().getHttpsUrl();
        Map map = new HashMap(4);
        //调用OCR接口获取数据并返回
        JSONObject jo = new JSONObject();
        if(StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.CON_RESOURCE_MEMORANDUM)){
            JSONObject ocrData = httpRequestUtil.ocr1(file);
            if(ocrData != null){
                //处理备忘录数据
                jo.put("signingDateStrName","date");
                jo.put("signingDateStrVal",ocrData.getString("date").trim());
                jo.put("signingDateName","date");
                jo.put("signingDateVal","");
                jo.put("signingDateLocName","date_loc");
                jo.put("signingDateLocVal",ocrData.getJSONObject("date_loc"));
                jo.put("buyerName","buyer");
                jo.put("buyerVal",ocrData.getString("buyer").trim());
                jo.put("buyerLocName","buyer_loc");
                jo.put("buyerLocVal",ocrData.getJSONObject("buyer_loc"));
                jo.put("sellerName","seller");
                jo.put("sellerVal",ocrData.getString("seller").trim());
                jo.put("sellerLocName","seller_loc");
                jo.put("sellerLocVal",ocrData.getJSONObject("seller_loc"));
                jo.put("deliveryTypeLocName","incoterms_loc");
                jo.put("deliveryTypeLocVal",ocrData.getJSONObject("incoterms_loc"));
                jo.put("loadingPortName","loading port");
                jo.put("loadingPortVal",ocrData.getString("loading port").trim());
                jo.put("loadingPortLocName","loading_port_loc");
                jo.put("loadingPortLocVal",ocrData.getJSONObject("loading_port_loc"));
                jo.put("unloadingPortName","discharge port");
//                jo.put("unloadingPortVal",ocrData.getString("discharge port").trim());

                if ((ocrData.getString("discharge port").trim().isEmpty())) {
                    jo.put("unloadingPortVal","No restriction");
                }else {
                    jo.put("unloadingPortVal",ocrData.getString("discharge port").trim());
                }

                jo.put("unloadingPortLocName","discharge_port_loc");
                jo.put("unloadingPortLocVal",ocrData.getJSONObject("discharge_port_loc"));
                jo.put("deliveryWindowName","delivery window");
                jo.put("deliveryWindowVal",ocrData.getString("delivery window").trim());
                jo.put("deliveryWindowLocName","delivery_window_loc");
                jo.put("deliveryWindowLocVal",ocrData.getJSONObject("delivery_window_loc"));
                jo.put("loadingOrUnloadingCapacityLocName","quantities_loc");
                jo.put("loadingOrUnloadingCapacityLocVal",ocrData.getJSONObject("quantities_loc"));
                jo.put("shipNameName","shape name");
                jo.put("shipNameVal",ocrData.getString("shape name").trim());
                jo.put("shipNameLocName","shape_name_loc");
                jo.put("shipNameLocVal",ocrData.getJSONObject("shape_name_loc"));
                jo.put("imoName","IMO");
                jo.put("imoVal",ocrData.getString("IMO").trim());
                jo.put("imoLocName","IMO_loc");
                jo.put("imoLocVal",ocrData.getJSONObject("IMO_loc"));
                jo.put("demurrageRateLocName","demurrage_rate_loc");
                jo.put("demurrageRateLocVal",ocrData.getJSONObject("demurrage_rate_loc"));
                jo.put("allowLoadingTimeLocName","laytime_loc");
                jo.put("allowLoadingTimeLocVal",ocrData.getJSONObject("laytime_loc"));
                jo.put("evaporationRateLocName","boil_off_rate_loc");
                jo.put("evaporationRateLocVal",ocrData.getJSONObject("boil_off_rate_loc"));
                jo.put("measurementClauseLocName","measurement_loc");
                jo.put("measurementClauseLocVal",ocrData.getJSONObject("measurement_loc"));
                jo.put("downFloatValueLocName","min_operational_tolerance_loc");
                jo.put("downFloatValueLocVal",ocrData.getJSONObject("min_operational_tolerance_loc"));
                jo.put("downFloatValueLoc",ocrData.getJSONObject("min_operational_tolerance_loc"));
                jo.put("upFloatValueLocName","max_operational_tolerance_loc");
                jo.put("upFloatValueLocVal",ocrData.getJSONObject("max_operational_tolerance_loc"));
                jo.put("upFloatValueLoc",ocrData.getJSONObject("max_operational_tolerance_loc"));
                jo.put("fileId",file.getOriginalFilename());
                jo.put("msg","SUCCESS");
                jo.put("detectStatus","1");
                jo.put("signingDate","");
                jo.put("buyer",ocrData.getString("full_buyer").trim());
//                jo.put("buyer",ocrData.getString("buyer").trim());
                jo.put("seller",ocrData.getString("full_seller").trim());
//                jo.put("seller",ocrData.getString("seller").trim());
                jo.put("fullBuyer",ocrData.getString("full_buyer").trim());
                jo.put("fullSeller",ocrData.getString("full_seller").trim());
                jo.put("loadingPort",ocrData.getString("loading port").trim());

                String buyerTradeBody = ocrData.getString("full_buyer").replaceAll("\\s", "");
                if (buyerTradeBody.endsWith("Ltd")) {
                    jo.put("buyerTradeBody", 2);
                } else if (buyerTradeBody.endsWith("ted")) {
                    jo.put("buyerTradeBody", 1);
                } else {
                    jo.put("buyerTradeBody", "");
                }

                String sellerTradeBody = ocrData.getString("full_seller").replaceAll("\\s", "");
                if (sellerTradeBody.endsWith("Ltd")) {
                    jo.put("sellerTradeBody", 2);
                } else if (sellerTradeBody.endsWith("ted")) {
                    jo.put("sellerTradeBody", 1);
                } else {
                    jo.put("sellerTradeBody", "");
                }

                if ((ocrData.getString("discharge port").trim().isEmpty())) {
                    jo.put("unloadingPort","No restriction");
                }else {
                    jo.put("unloadingPort",ocrData.getString("discharge port").trim());
                }
                jo.put("deliveryWindow",ocrData.getString("delivery window").trim());

                String shapeName = ocrData.getString("shape name").trim();
                String modifiedShapeName = shapeName.replaceAll("(?<=\\p{Lu})", " ");
                String uppercaseShapeName = modifiedShapeName.toUpperCase();
                jo.put("shipName",uppercaseShapeName);
                jo.put("imo",ocrData.getString("IMO").trim());
                try {
                    jo.put("downFloatValueName","min_operational_tolerance");
                    jo.put("downFloatValueVal",new BigDecimal(ocrData.getString("min_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("downFloatValue",new BigDecimal(ocrData.getString("min_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("downFloatValueName","");
                    jo.put("downFloatValueVal","");
                    jo.put("downFloatValue",0);
                }
                try {
                    jo.put("upFloatValueName","max_operational_tolerance");
                    jo.put("upFloatValueVal",new BigDecimal(ocrData.getString("max_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("upFloatValue",new BigDecimal(ocrData.getString("max_operational_tolerance").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("upFloatValueName","");
                    jo.put("upFloatValueVal","");
                    jo.put("upFloatValue",0);
                }
                try {
                    jo.put("measurementClauseName","measurement");
                    jo.put("measurementClauseVal",ocrData.getString("measurement").replaceAll(",","").replaceAll("，","").trim());
                    jo.put("measurementClause",ocrData.getString("measurement").replaceAll(",","").replaceAll("，","").trim());
                }catch (Exception e){
                    jo.put("measurementClauseName","");
                    jo.put("measurementClauseVal","");
                    jo.put("measurementClause","");
                }
                try {
                    String quantitiesString = ocrData.getString("quantities").replaceAll("[Oo]", "0").replaceAll("[^0-9]", "");
                    BigDecimal quantities = new BigDecimal(quantitiesString);
                    jo.put("loadingOrUnloadingCapacityName", "quantities");
                    jo.put("loadingOrUnloadingCapacityVal", quantities);
                    jo.put("loadingOrUnloadingCapacity", quantities);
                }catch (Exception e){
                    jo.put("loadingOrUnloadingCapacityName","");
                    jo.put("loadingOrUnloadingCapacityVal","");
                    jo.put("loadingOrUnloadingCapacity","");
                }
                try {
                    jo.put("demurrageRateName","demurrage rate");
                    jo.put("demurrageRateVal",new BigDecimal(ocrData.getString("demurrage rate").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("demurrageRate",new BigDecimal(ocrData.getString("demurrage rate").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("demurrageRateName","");
                    jo.put("demurrageRateVal","");
                    jo.put("demurrageRate","");
                }
                try {
                    jo.put("evaporationRateName","boil off rate");
                    jo.put("evaporationRateVal",new BigDecimal(ocrData.getString("boil off rate").replaceAll(",","").replaceAll("，","").trim()).divide(new BigDecimal(100)));
                    jo.put("evaporationRate",new BigDecimal(ocrData.getString("boil off rate").replaceAll(",","").replaceAll("，","").trim()).divide(new BigDecimal(100)));
                }catch (Exception e){
                    jo.put("evaporationRateName","");
                    jo.put("evaporationRateVal","");
                    jo.put("evaporationRate","");
                }
                try {
                    jo.put("allowLoadingTimeName","laytime");
                    jo.put("allowLoadingTimeVal",ocrData.getInteger("laytime"));
                    jo.put("allowLoadingTime",ocrData.getInteger("laytime"));
                }catch (Exception e){
                    jo.put("allowLoadingTimeName","");
                    jo.put("allowLoadingTimeVal","");
                }
                String deliveryType = ocrData.getString("incoterms_info").trim();
                jo.put("deliveryTypeName","incoterms_info");
                if(deliveryType.equals("FOB")){
                    jo.put("deliveryType",1);
                    jo.put("deliveryTypeVal","FOB");

                }else if(deliveryType.equals("DES")){
                    jo.put("deliveryTypeVal","DES");
                    jo.put("deliveryType",2);
                }
                String demurrageType = ocrData.getString("demurrage_type").trim();
                jo.put("currencyName","demurrage_type");
                if(demurrageType.equals("USD")){
                    jo.put("currency",1);
                    jo.put("currencyVal","USD");
                } else if(demurrageType.equals("CNY")){
                    jo.put("currency",2);
                    jo.put("currencyVal","CNY");
                } else if(demurrageType.equals("EUR")) {
                    jo.put("currency", 3);
                    jo.put("currencyVal","EUR");
                } else if(demurrageType.equals("GBP")) {
                    jo.put("currency", 4);
                    jo.put("currencyVal","GBP");
                } else if(demurrageType.equals("CAD")) {
                    jo.put("currency", 5);
                    jo.put("currencyVal","CAD");
                } else if(demurrageType.equals("JPY")) {
                    jo.put("currency", 6);
                    jo.put("currencyVal","JPY");
                } else if(demurrageType.equals("INR")) {
                    jo.put("currency", 7);
                    jo.put("currencyVal","INR");
                } else if(demurrageType.equals("PENCE")) {
                    jo.put("currency", 8);
                    jo.put("currencyVal","PENCE");
                } else if(demurrageType.equals("RUB")) {
                    jo.put("currency", 9);
                    jo.put("currencyVal","RUB");
                }
                String quantitiesType = ocrData.getString("quantities_type").trim();
                jo.put("unitName","quantities_type");
                if(quantitiesType.equals("MMBTU")){
                    jo.put("unit",1);
                    jo.put("unitVal","MMBTU");
                }else if(quantitiesType.equals("m³")){
                    jo.put("unit",2);
                    jo.put("unitVal","m³");
                }else if(quantitiesType.equals("mt")) {
                    jo.put("unit",3);
                    jo.put("unitVal","mt");
                }
                map.put("contractData",jo);
            }else{
                map.put("contractData",jo);
            }
            map.put("path",filePath);
            conResourceMemorandumPositionService.saveInfo(map,filePath);
        }
        else if (StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.CON_SHIPPING)){
            JSONObject ocrData = httpRequestUtil.ocr2(file);
            if(ocrData != null){
                //处理船运数据
                jo.put("tenantName","Charterer");
                jo.put("tenantLocName","Charterer_loc");
                jo.put("shipownerName","Owner");
                jo.put("shipownerLocName","Owner_loc");
                jo.put("shipNameName","Vessel");
                jo.put("shipNameLocName","Vessel_loc");
                jo.put("leaseTermStrName","Period");
                jo.put("leaseTermStrLocName","Period_loc");
                jo.put("deliveryNoticeName","Delivery notices");
                jo.put("deliveryNoticeLocName","Delivery notices_loc");
                jo.put("deliveryDateName","Delivery Laycan");
                jo.put("deliveryDateLocName","Delivery Laycan_loc");
                jo.put("placeOfDeliveryOfShipName","Delivery location");
                jo.put("placeOfDeliveryOfShipLocName","Delivery location_loc");
                jo.put("deliveryStatusName","Delivery condition");
                jo.put("deliveryStatusLocName","Delivery condition_loc");
                jo.put("placeOfRedeliveryOfShipName","Re-delivery");
                jo.put("placeOfRedeliveryOfShipLocName","Re-delivery_loc");
                jo.put("redeliveryStatusName","Re-delivery Condition");
                jo.put("redeliveryStatusLocName","Re-delivery Condition_loc");
                jo.put("redeliveryNoticeName","Re-delivery notices");
                jo.put("redeliveryNoticeLocName","Re-delivery notices_loc");
                jo.put("foeName","FOE");
                jo.put("foeLocName","FOE_loc");
                jo.put("fuelUsagePrinciplesName","Fuel Price");
                jo.put("fuelUsagePrinciplesLocName","Fuel Price_loc");

                jo.put("tenantVal",ocrData.getString("Charterer").trim());
                jo.put("tenant",ocrData.getString("Charterer").trim());
                jo.put("tenantLocVal",ocrData.getJSONObject("Charterer_loc"));
                jo.put("shipownerVal",ocrData.getString("Owner").trim());
                jo.put("shipowner",ocrData.getString("Owner").trim());
                jo.put("shipownerLocVal",ocrData.getJSONObject("Owner_loc"));
                jo.put("shipNameVal",ocrData.getString("Vessel").trim());
                jo.put("shipName",ocrData.getString("Vessel").trim());
                jo.put("shipNameLocVal",ocrData.getJSONObject("Vessel_loc"));
                jo.put("leaseTermStrLocVal",ocrData.getJSONObject("Period_loc"));
                jo.put("deliveryNoticeVal",ocrData.getString("Delivery notices").trim());
                jo.put("deliveryNoticeLocVal",ocrData.getJSONObject("Delivery notices_loc"));
                jo.put("deliveryDateVal",ocrData.getString("Delivery Laycan").trim());
                jo.put("deliveryDate","");
                jo.put("deliveryDateLocVal",ocrData.getJSONObject("Delivery Laycan_loc"));
                jo.put("placeOfDeliveryOfShipVal",ocrData.getString("Delivery location").trim());
                jo.put("placeOfDeliveryOfShipLocVal",ocrData.getJSONObject("Delivery location_loc"));
                jo.put("deliveryStatusVal",ocrData.getString("Delivery condition").trim());
                jo.put("deliveryStatusLocVal",ocrData.getJSONObject("Delivery condition_loc"));
                jo.put("placeOfRedeliveryOfShipVal",ocrData.getString("Re-delivery").trim());
                jo.put("placeOfRedeliveryOfShipLocVal",ocrData.getJSONObject("Re-delivery_loc"));

                jo.put("redeliveryStatusLocVal",ocrData.getJSONObject("Re-delivery Condition_loc"));
                jo.put("redeliveryNoticeVal",ocrData.getString("Re-delivery notices").trim());
                jo.put("redeliveryNoticeLocVal",ocrData.getJSONObject("Re-delivery notices_loc"));

                jo.put("foeLocVal",ocrData.getJSONObject("FOE_loc"));

                jo.put("fuelUsagePrinciplesLocVal",ocrData.getJSONObject("Fuel Price_loc"));
                try {
                    jo.put("redeliveryStatusName","Re-delivery Condition");
                    jo.put("redeliveryStatusVal",new BigDecimal(ocrData.getString("Re-delivery Condition").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("redeliveryStatus",new BigDecimal(ocrData.getString("Re-delivery Condition").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("redeliveryStatusName","");
                    jo.put("redeliveryStatusVal","");
                    jo.put("redeliveryStatus","");
                }
                try {
                    jo.put("foeName","FOE");
                    jo.put("foeVal",new BigDecimal(ocrData.getString("FOE").replaceAll(",","").replaceAll("，","").trim()));
                    jo.put("foe",new BigDecimal(ocrData.getString("FOE").replaceAll(",","").replaceAll("，","").trim()));
                }catch (Exception e){
                    jo.put("foeName","");
                    jo.put("foeVal","");
                    jo.put("foe","");
                }
                String fuelUsagePrinciples = ocrData.getString("Fuel Price").trim();
                jo.put("fuelUsagePrinciplesName","Fuel Price");
                switch (fuelUsagePrinciples) {
                    case "FIFO":
                        jo.put("fuelUsagePrinciples", 1);
                        jo.put("fuelUsagePrinciplesVal", "FIFO");
                        break;
                    case "LIFO":
                        jo.put("fuelUsagePrinciples", 2);
                        jo.put("fuelUsagePrinciplesVal", "LIFO");
                        break;
                    case "LILO":
                        jo.put("fuelUsagePrinciples", 3);
                        jo.put("fuelUsagePrinciplesVal", "LILO");
                        break;
                }

                String tenant = ocrData.getString("Charterer").replaceAll("\\s", "");
                if (tenant.endsWith("Ltd.")) {
                   jo.put("tradeBody", 2);
                } else if (tenant.endsWith("ted.")) {
                    jo.put("tradeBody", 1);
                } else {
                    jo.put("tradeBody", "");
                }
                String leaseTermStr = ocrData.getString("Period").trim();
                BigDecimal leaseTerm = extractLeaseTerm(leaseTermStr);
                Integer leaseTermValueUp = extractX1(leaseTermStr);
                Integer leaseTermValueUpDown = extractX2(leaseTermStr);
                jo.put("leaseTerm",leaseTerm);
                jo.put("leaseTermValueUp",leaseTermValueUp);
                jo.put("leaseTermValueUpDown",leaseTermValueUpDown);
            }
            map.put("contractData",jo);
            map.put("path",filePath);
            conResourceMemorandumPositionService.saveInfo(map,filePath);
        }
        else if (StringUtils.isNotBlank(contractType) && contractType.equals(ModuleConst.TEMPLATE_FILE)){
            int lastIndex = filePath.lastIndexOf("/");
            String fileName = filePath.substring(lastIndex + 1);
            int dotIndex = fileName.lastIndexOf(".");
            String fileNameWithout = fileName.substring(0, dotIndex);
            map.put("contractData",jo);
            map.put("fileName",fileNameWithout);
            map.put("path",filePath);
        }
        else{
            map.put("contractData",jo);
            map.put("path",filePath);
        }
        //保存redis中
        //redisService.setCacheMap(file.getName(),map);
        return JsonResult.success(map);
    }

    /**
     * 前端通过文件名轮询ocr返回集合
     * @param fileName
     * @return
     */
    public JsonResult getAnalysisInfo(String fileName){
        //从redis中获取ocr识别内容
        Map map = redisService.getCacheMap(fileName);
        return JsonResult.success(map);
    }

    @PostMapping("/supplyDisPatchFiles")
    @ResponseBody
    public JsonResult<Object> supplyDisPatchFiles(@RequestParam("file") MultipartFile file,String id) {

        FileUtils.checkFileName(file);
        String url = "";
        try {

            R<SysFile> result = remoteFileService.upload(file);
            if (result.getCode() != R.SUCCESS) {
                throw new BusException("文件服务器连接失败", BaseResultCode.GENERAL_ERROR);
            }

            url = result.getData().getHttpUrl();
        } catch (Exception e) {
            return JsonResult.failed("上传失败，原因：" + e.getMessage());
        }

//        String url = httpRequestUtil.upload(file);
        int lastIndex = url.lastIndexOf("/");
        String fileName = url.substring(lastIndex + 1);
        int dotIndex = fileName.lastIndexOf(".");
        String fileNameWithout = fileName.substring(0, dotIndex);

        ConFiles conFiles = new ConFiles();
        conFiles.setUrl(url);
        conFiles.setConId(Long.valueOf(id));
        conFiles.setFileType(3);
        conFiles.setFileName(fileNameWithout);
        conFilesService.save(conFiles);
        return JsonResult.success();
    }

    /**
     * 删除附件
     *
     * @return
     */
    @DeleteMapping("/delConFile")
    @ResponseBody
    @Log(title = "删除附件",businessType = BusinessType.DELETE)
    public JsonResult<Object> delConFile(Long id,Long conId)  {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("id",id);
        queryWrapper.eq("file_type",2);
        conFilesService.remove(queryWrapper);
        conOperateService.saveByCon("删除附件",conId);
        return JsonResult.success();
    }

    /**
     * 删除标签
     *
     * @return
     */
    @DeleteMapping("/delConLabel")
    @ResponseBody
    @Log(title = "删除标签",businessType = BusinessType.DELETE)
    public JsonResult<Object> delConLabel(Long id,Long conId)  {
        ConAllLabel conAllLabel = conAllLabelService.getById(id);
        if(conAllLabel != null){
            if(!conAllLabel.getUserId().toString().equals(SecurityUtils.getStringUserId()) && conAllLabel.getLabelId() == null){
                throw new BusException("你不能删除该标签!", BaseResultCode.GENERAL_ERROR);
            }
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("id",id);
        conAllLabelService.remove(queryWrapper);
        conOperateService.saveByCon("删除标签",conId);
        return JsonResult.success();
    }

    /**
     * 修改合同附件信息
     * @param conFiles
     * @return
     */
    @PostMapping("/updateContractFiles")
    @ResponseBody
    @Log(title = "修改合同附件信息",businessType = BusinessType.UPDATE)
    public JsonResult<Object> updateContractFiles(@RequestBody ConFiles conFiles){
        conFilesService.updateById(conFiles);
        conOperateService.saveByCon("修改合同附件",conFiles.getConId());
        return JsonResult.success();
    }


    @GetMapping("/downloadContractWithPageNum")
    public JsonResult downloadContractWithPageNum(Long id,String contractName,int startPage,int endPage){
        ConFiles conFiles = conFilesService.getContractMainFile(id);
        if(conFiles == null){
            throw new BusException("合同文件不存在!",BaseResultCode.GENERAL_ERROR);
        }
        ExportContractFileTask task = new ExportContractFileTask();
        String path = conFiles.getUrl();
        String CsoldPart = "http://10.75.34.224:9300/statics";
        String ZsoldPart = "http://10.75.33.149:9300/statics";
        String CsPart = "https://lngshippingcs.cgp.cnooc/api/file/statics";
        String ZsPart = "https://lngshipping.cgp.cnooc/api/file/statics";

        String newUrl = "";
        if (path.contains("https://lngshipping.cgp.cnooc")) {
            newUrl = path.replace(ZsPart, ZsoldPart);
        }else if (path.contains("https://lngshippingcs.cgp.cnooc")){
            newUrl = path.replace(CsPart, CsoldPart);
        }else {
            newUrl = path;
        }
        task.setFilePath(newUrl);
        task.setFrom(startPage);
        task.setEnd(endPage);
        task.setHttpRequestUtil(httpRequestUtil);
        task.setSpringUtil(springUtil);

        TimeZone timeZone = TimeZone.getTimeZone("GMT+8");
        Date currentDateTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        sdf.setTimeZone(timeZone);
        String formattedDateTime = sdf.format(currentDateTime);
        String DownloadFileName = formattedDateTime+"-"+contractName+"-"+startPage+"-"+endPage+".pdf";
        task.setDownloadFileName(DownloadFileName);
        exportService.export(task);
        return JsonResult.success();
    }

    /**
     * 查看页面 上传合同文件中的保存文件
     * @param conFiles
     * @return
     */
    @PostMapping("/modifyFile")
    public JsonResult modifyFile(@RequestBody ConFiles conFiles){
        if(null == conFiles.getConId()){
           return JsonResult.failed("合同id不能为空");
        }
        conFilesService.saveFile(conFiles);
        //更新合同状态值
        conFilesService.updateConStatus(conFiles.getConId());
        return JsonResult.success();
    }

    /**
     * 根据模块查询所有合同
     * @param module
     * @return
     */
    @GetMapping("/getAllContractByModule")
    public JsonResult getAllContractByModule(Integer module){
        List<ContractBaseBean> list = ((ContractBaseService)springUtil.getBean(ModuleConst.getContractBaseBean(module))).allContracts();
        List<Map<String,Object>> result = new ArrayList<>();
        for(ContractBaseBean contractBaseBean: list){
            Map<String,Object> map = new HashMap<>();
            map.put("id",contractBaseBean.getId().toString());
            map.put("contractName",contractBaseBean.getContractName());
            result.add(map);
        }
        return JsonResult.success(result);
    }

    private JSONObject createSearchItem(Field field) {
        JSONObject item = new JSONObject();
        Label label = field.getAnnotation(Label.class);
        SearchItem searchItem = field.getAnnotation(SearchItem.class);
        item.put("priority", label.priority());
        item.put("name", label.value()[0]);
        item.put("key", field.getName());
        if (searchItem != null && searchItem.width() != 0) {
            item.put("importminwidth", searchItem.width() + "px");
        }
        String type = getFormItemType(field);
        item.put("type", type);
        if(type.equals("checkbox")){
            item.put("key", field.getName() + "ListForSearch");
        }
        JSONArray options = setItemByProvider(field, item);

        item.put("options", options);
        /*if (options != null && options.size() == 0) {
            return null;
        }*/
        return item;
    }

    private String getFormItemType(Field field) {
        Label label = field.getAnnotation(Label.class);
        if (!label.contentProvider().equals(Object.class)) {
            ContentProvider provider = (ContentProvider) springUtil.getBean(label.contentProvider());
            if (provider instanceof TreeProvider) {
                return "cascader";
            }
            if (provider instanceof ConstantTypeProvider) {
                return "select";
            }
        }
        if (!label.type().equals("text")) {
            return label.type();
        }
        if (!"".equals(label.enumContent())) {
            if (label.multiSelect()) {
                return "checkbox";
            }
            return "select";
        }
        if (label.longText()) {
            return "textarea";
        }
        if (field.getType().equals(String.class)) {
            return "text";
        }
        if (field.getType().equals(Integer.class)) {
            return "number";
        }
        if (field.getType().equals(Long.class)) {
            return "text";
        }
        if (field.getType().equals(BigDecimal.class)) {
            return "number";
        }
        if (field.getType().equals(Double.class)) {
            return "text";
        }
        if (field.getType().equals(Boolean.class)) {
            return "radio";
        }
        if (field.getType().equals(Date.class)) {
            return "date";
        }
        throw new SystemException("找不到字段[" + field.getDeclaringClass().getName() + "." + field.getName() + "]对应的表单项类型");
    }
    private JSONArray setItemByProvider(Field field, JSONObject item) {
        JSONArray options = null;
        Label label = field.getAnnotation(Label.class);
        if (!label.contentProvider().equals(Object.class)) {
            ContentProvider provider = (ContentProvider) springUtil.getBean(label.contentProvider());
            options = provider.getOptions(field);
        }
        if (!label.enumContent().equals("")) {
            String enumKey = label.enumContent();
            if (enumKey.startsWith("join:")) {
                String joinEntityName = enumKey.substring(5);
                String cascadeJoin = label.cascadeJoin();
                if (!"".equals(cascadeJoin)) {
                    options = new JSONArray();
                } else {
                    BaseBean t = enumContentProvider.getBeanInstance(joinEntityName);
                    handlerJoinCondition(t, field, label);
                    BaseServiceImpl service = enumContentProvider.getService(joinEntityName);
                    options = createOption(service, t);
                }
            } else {
                options = enumContentProvider.getOptions(field);
            }
        }
        if (label.boolContent()) {
            options = booleanContentProvider.getOptions(field);
        }
        return options;
    }
    private void handlerJoinCondition(BaseBean t, Field field, Label label) {
        String joinCondition = label.joinCondition();
        if (!"".equals(joinCondition)) {
            Interpreter interpreter = new Interpreter();
            try {
                interpreter.set("join", t);
                interpreter.set("user", currentUser());
                interpreter.set("springUtil", springUtil);
                for (String expression : joinCondition.split(";")) {
                    interpreter.eval(expression);
                }
            } catch (EvalError e) {
                throw new SystemException("连接表达式设置错误：位于 " + field.getDeclaringClass().getName() + "." + field.getName());
            }
        }
    }
    private JSONArray createOption(BaseService service, BaseBean t) {
        t.setPageSize(Integer.MAX_VALUE);
        t.setPageNum(1);
        List<BaseBean> list = service.listForSearchBox(t);
        JSONArray options = new JSONArray();
        for (Object object : list) {
            Joinable j = (Joinable) object;
            JSONObject option = enumContentProvider.createOption(j.getValue(), j.getLabel());
            options.add(option);
        }
        return options;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        searchItems.clear();
        tableColumns.clear();
        List<Class<?>> classes = PackageUtil.getClasses(ConstantUtil.BEAN_PACKAGE);
        for (Class<?> clazz : classes) {
            for (Field field : FieldUtil.getAllFields(clazz)) {
                SearchItem[] fieldSearchItems = field.getAnnotationsByType(SearchItem.class);
                TableColumn[] fieldTableColumns = field.getAnnotationsByType(TableColumn.class);
                for (SearchItem searchItem : fieldSearchItems) {
                    if (field.getAnnotation(Label.class) == null) {
                        throw new SystemException("Class [" + clazz.getName() + "] field [" + field.getName() + "] must hava annotation [" + Label.class.getName() + "]");
                    }
                    String group = searchItem.group();
                    if ("".equals(group)) {
                        group = StringUtil.camelhumpToUnderline(clazz.getSimpleName());
                    }
                    List<Field> items = searchItems.get(group);
                    if (items == null) {
                        items = new ArrayList<>();
                        searchItems.put(group, items);
                    }
                    items.add(field);
                }
                for (TableColumn tableColumn : fieldTableColumns) {
                    if (field.getAnnotation(Label.class) == null) {
                        throw new SystemException("Class [" + clazz.getName() + "] field [" + field.getName() + "] must hava annotation [" + Label.class.getName() + "]");
                    }
                    String group = tableColumn.group();
                    if ("".equals(group)) {
                        group = StringUtil.camelhumpToUnderline(clazz.getSimpleName());
                    }
                    List<Field> items = tableColumns.get(group);
                    if (items == null) {
                        items = new ArrayList<>();
                        tableColumns.put(group, items);
                    }
                    items.add(field);
                }
            }
        }
        for (String group : searchItems.keySet()) {
            searchItems.get(group).sort(new Comparator<Field>() {
                @Override
                public int compare(Field o1, Field o2) {
                    return o1.getAnnotation(SearchItem.class).priority() - o2.getAnnotation(SearchItem.class).priority();
                }
            });
        }
        for (String group : tableColumns.keySet()) {
            tableColumns.get(group).sort(new Comparator<Field>() {
                @Override
                public int compare(Field o1, Field o2) {
                    return o1.getAnnotation(TableColumn.class).priority() - o2.getAnnotation(TableColumn.class).priority();
                }
            });
        }
    }

    /**
     * 转换日期格式
     * @param inputDate
     * @return
     */
    public static String convertDate(String inputDate) {
        try {
            SimpleDateFormat inputDateFormat = new SimpleDateFormat("dd MMMM yyyy");
            SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");

            inputDate = inputDate.replaceAll("th", "");

            Date date = inputDateFormat.parse(inputDate);

            String formattedDate = outputDateFormat.format(date);

            return formattedDate;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 船运合同ocr识别，租期日期处理
     * @param input
     * @return
     */
    private static BigDecimal extractLeaseTerm(String input) {
//        Pattern pattern = Pattern.compile("(\\d+)([a-zA-Z]+)");
//        Pattern pattern = Pattern.compile("(\\s?)(\\d+)([a-zA-Z]+)");
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(input);

        if (matcher.find()) {
            return new BigDecimal(matcher.group());
        } else {
            return null;
        }
    }

    /**
     * 船运合同ocr识别，租期日期上限处理
     * @param input
     * @return
     */
    private static Integer extractX1(String input) {
        Pattern pattern = Pattern.compile("plus.*?(\\d+)");
        Matcher matcher = pattern.matcher(input);

        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        } else {
            return 0;
        }
    }

    /**
     * 船运合同ocr识别，租期日期下限处理
     * @param input
     * @return
     */
    private static Integer extractX2(String input) {
        Pattern pattern = Pattern.compile("minus.*?(\\d+)");
        Matcher matcher = pattern.matcher(input);

        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        } else {
            return 0;
        }
    }

    /**
     * 资金结算--分页
     *
     * @param fundManagementDto
     * @return
     */
    @PostMapping("/getPayFundManagements")
    public JsonResult<Page<PayFundManagement>> page(@RequestBody PayFundManagementDto fundManagementDto) {
        PayFundManagement payFundManagement = new PayFundManagement();
        BeanUtils.copyProperties(fundManagementDto,payFundManagement);
        Page<PayFundManagement> page = payFundManagementService.page(payFundManagement,new QueryWrapper<PayFundManagement>().eq("affiliated_contract_id",payFundManagement.getAffiliatedContractId()));
        return JsonResult.success(page);
    }

    @GetMapping("/main/conFiles/{conId}")
    public JsonResult getConFileByConId(@PathVariable("conId") Long conId){
        ConFiles conFiles = conFilesService.getContractMainFile(conId);
       return JsonResult.success(conFiles);
    }

}
